﻿/***********************************
 * Developer: Lio.Huang
 * Create Date：2018-11-16
 * 
 * Last Update：
 * 2019-01-07  1.Add this.context.State != ConnectionState.Connecting
 * 2019-01-21  1.Add UnitOfWork(string dbAliase = "")
 **********************************/

using System;
using System.Collections.Generic;
using System.Data;
using housingsafety.server.Repository.Banana.Interface;

namespace housingsafety.server.Repository.Banana
{
    /// <summary>
    /// 工作单元基类|
    /// Base UnitOfWork
    /// </summary>
    public class UnitOfWork : Interface.IUnitOfWork, IRepositoryFactory
    {
        private Dictionary<Type, object> _repositories;
        private readonly IDbConnection _context;
        private readonly IDbTransaction _transaction;

        private bool _disposed = false;
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    //clear repo
                    if (_repositories != null)
                    {
                        _repositories.Clear();
                    }
                    if (_context.State != ConnectionState.Closed)
                        _context.Close();
                }
            }

            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 工作单元基类|
        /// Base UnitOfWork
        /// </summary>
        public UnitOfWork(IDbConnection context)
        {
            this._context = context;
            if (this._context.State == ConnectionState.Closed && this._context.State != ConnectionState.Connecting)
            {
                this._context.Open();
            }
            _transaction = this._context.BeginTransaction();
        }

        /// <summary>
        /// 工作单元基类|
        /// Base UnitOfWork
        /// </summary>
        public UnitOfWork(string dbAliase = "")
        {
            this._context = ConnectionBuilder.CreateConnection(dbAliase);
            this._context.Open();
            this._transaction = this._context.BeginTransaction();
        }

        /// <summary>
        /// 提交事务|
        /// transaction commit
        /// </summary>
        public void Commit()
        {
            this._transaction.Commit();
        }

        /// <summary>
        /// 事务回滚|
        /// transaction rollback
        /// </summary>
        public void Rollback()
        {
            this._transaction.Rollback();
        }

        /// <summary>
        /// 获取仓储|
        /// Get a repository
        /// </summary> 
        public Interface.IRepository<T> GetRepository<T>() where T : class, Models.IEntity
        { 
            if (_repositories == null)
            {
                _repositories = new Dictionary<Type, object>();
            }
            var type = typeof(T);
            if (!_repositories.ContainsKey(type))
            {
                var repositoryType = typeof(Repository<>);
                var repositoryInstance = Activator.CreateInstance(repositoryType.MakeGenericType(typeof(T)), _context, _transaction);
                _repositories.Add(type, repositoryInstance);
            } 
            return (Interface.IRepository<T>)_repositories[type];
        }

    }
}
